import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import java.util.ListIterator;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;

/**
 * A simple class that opens a server socket, and prints each message received
 * to the console.
 * @author Graeme Stevenson (graeme.stevenson@ucd.ie)
 * @author Amended by Tom Crowe (09137149@ucdconnect.ie)
 * @tinker Amended by Kevin Lally
 */
public class FlightInfoService implements FlightInfoMsgs{
       
        /**
         * Accept this many connections. Protection against a SYN attack.
         */
        private int my_backlog = 5;

        /**
         * The server socket.
         */
        private ServerSocket my_serverSocket;
           
        /**
         * The default server port.
         */
        private static final int DEFAULT_PORT = 10985;

        // Vector - because eventually it will be a multi-threaded server.
        private Vector<FlightInfo> FlightInfoList = null;
   
        /**
         * The service type you want to register. The first part should be a unique
         * name to identify your services belonging to your project. The second part
         * identifies the transport. The last part identifies the domain. Note that
         * this must end with a period. Service types and transports typically begin
         * with an underscore (e.g. _tcp or _udp). Each part is separated by a
         * period. E.g. "printer._tcp.local.".
         */
        public static final String SERVICE_TYPE = "GroupD._udp.local.";

        /**
         * A unique name for the service you want to register; e.g.
         * "casl_level3_colour".
         */
        public static final String SERVICE_NAME = "FlightInfoServices";

        /**
         * Create the server socket.
         * @param a_port the port that the server socket should listen on.
         */
        public FlightInfoService(int a_port) throws IOException {

              
       
                try {
                        my_serverSocket = new ServerSocket(a_port, my_backlog);
                        System.out.println("TCP socket listening on port " + a_port);
                } catch (SecurityException se) {
                        se.printStackTrace();
                }
        }

        /**
         * Listens on the server socket forever and prints each incoming message to the console.
         * Each connection is dealt with sequentially before the next connection is accepted.
         */
        public void listen() {
                while (true) {
                        Socket socket = null;
                        Socket socket2 = null;
                        BufferedReader in = null;
                       
                String filename = "flightlistArr.txt";
                String filename2 = "flightlistDepartures.txt";
                String searchFor = "";
                BufferedReader in2 = null;
                int choice = 0;
              // 
                       
                        try {
                               
                                // Listens for a connection to be made to this socket.
                                socket = my_serverSocket.accept();

                                // Wrap a buffered reader round the raw socket input stream.
                                // Then read in the message and print the message to the console                                
                                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                                String msg = in.readLine();
                               
                                System.out.println("Received message: " + msg);
                                String flightRow="1";
                                String NOTFOUND ="qqq";
                            //    while(flightRow!=null){
                                   try {
                          
                               searchFor=msg;
                               in = new BufferedReader(new FileReader(new File(filename)));
                               
                           } catch (IOException e) {
                           }
                          // String flightRow = null;
                           int currentLine = 0;
                           // this will be set to true if the string was found
                           boolean foundString = false;
                           while (true) {
                               currentLine++;
                               // get a line of text from the file
                               try {
                                   flightRow = in.readLine();
                               } catch (IOException e) {
                                   break;
                               }
                               // checks to see if the file ended (in.readLine() returns
                               // null if the end is reached)
                               if (flightRow == null) {
                                   break;
                               }
                               if (flightRow.indexOf(searchFor) == -1) {
                                   continue;
                               } else {
                            	   foundString = true;
                                   break;
                               }
                           }
                           if (!foundString)
                               System.out
                                       .println("Sorry you entered the wrong flight number.");


                                 
                               
                                	   
                                    	sendReply( flightRow, socket);
                                       
                                   
                                 
                                     
                                  // break;
                               
                               
                           
            
                           try {
                               in.close();
                           }

                           catch (IOException ioe) {
                           }
                         
                        
                        
               
                        }
                        catch (IOException ioe) {
                                ioe.printStackTrace();
                        }
                        catch (SecurityException se) {
                                se.printStackTrace();
                        }
                        finally {
                                try {
                                      in.close();
                                     socket.close();
                                        System.out.println("Have executed finally.");
                                } catch (IOException ioe) {
                                        ioe.printStackTrace();
                                }
                        }
                }
        }


       
        private void sendReply(String retMsg, Socket sock) throws IOException, SecurityException {

                // Send the response back to the client.;
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
                out.write(retMsg,0,retMsg.length());
               
                out.newLine();
                out.flush();
                System.out.println("Message  to Client: " + retMsg);

                // Tidy up
               out.close();

        }
       
        /**
         * Parses the arguments to the program and create the server socket. Also register
         * the service (starting a mDNS instance) and then listen for connections on the
         * server socket ad infinitum.
         * @param args the program arguments. Should take the form &lt;port&gt;
         */
        public static void main(String[] args) throws IOException{
                int port = 0;
                FlightInfoService server = null;

                // Check we have the right number of arguments and parse
                if (args.length == 1) {
                        try {
                                port = Integer.valueOf(args[0]);
                        } catch (NumberFormatException nfe) {
                                System.err.println("The value provided for the port is not an integer");
                                nfe.printStackTrace();
                                System.exit(1);
                        }
                        if (port < 1){
                                System.err.println("The values provided for the port must be > 0");
                                System.exit(1);
                        }
                }
                if (args.length == 0)
                        port = DEFAULT_PORT;
                else {
                        System.out.println("Usage: java FlightInfoServices <port (optional)>");
                        System.out.println("Default port: " + DEFAULT_PORT);
                }
                       
                // Create the server before registering service in case there is a port clash for my server
                try {
                        server = new FlightInfoService(port);
                } catch (IOException ioe) {
                        System.err.println("The server could not be started - possibly port clash on port: " + port);
                        ioe.printStackTrace();
                        System.exit(1);
                }
               
                // Register this service with jmDns (zeroconf impl)
                JmDNS jmdns = JmDNS.create();
                ServiceInfo info = ServiceInfo.create(SERVICE_TYPE, SERVICE_NAME, port, 0, 0,
                                                        "a_property=some_value");
                jmdns.registerService(info);
                System.out.println("Registered Service as " + info); // note that the
                                                         // service name may
                                                         // have changed if a
                                                         // service with that
                                                         // name was already
                                                         // registered.

                // Listen on the server socket. This will run until the program is killed.
                server.listen();

                // Clean up jmDns registration
                jmdns.unregisterService(info);
                jmdns.close();

                // Clean up server socket
                server.my_serverSocket.close();

        }
} // end class
